package org.dftproject.pgv.core.racp;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SessionManager {
	
	private static final Log log = LogFactory.getLog(SessionManager.class);

	private static final SessionManager singleton = new SessionManager();

	private final Map<String, Session> sessions = new HashMap<String, Session>();

	private SessionManager() {
	}

	/**
	 * Returns the singleton instance.
	 * @return the session manager
	 */
	public static SessionManager getDefault() {
		return singleton;
	}

	/**
	 * Returns the cached session for the given PGV website. The session will be
	 * created if it does not already exist.
	 * @param url the base URL of a PGV website (excluding a filename)
	 * @return the session
	 */
	public Session getSession(String url) {
		return getSession(url, null, null);
	}

	/**
	 * Returns the cached session for the given PGV website. The session will be
	 * created if it does not already exist.
	 * @param url the base URL of a PGV website (excluding a filename)
	 * @param username a username
	 * @param password a password
	 * @return the session
	 */
	public Session getSession(String url, String username, String password) {
		if (!url.endsWith("/"))
			url += "/";
		String key = getSessionKey(url, username, password);
		
		// Try to get the session from the cache

		Session session = sessions.get(key);
		if (session == null || !session.isValid()) {
			log.info("No valid session for " + url + " with username " + username);
			
			synchronized (sessions) {
				if (session != null)
					sessions.remove(key);
				
				// Try to get the session from the cache again, in case
				// another thread already created it

				session = sessions.get(key);
				if (session == null) {
					// Create and start the session

					log.info("Starting a session for " + url + " with username " + username);
					
					session = new Session(url, username, password);
					if (session.connect()) {
						sessions.put(key, session);
					} else {
						return null;
					}
				}
			}
		}

		return session;
	}
	
	protected String getSessionKey(String url, String username, String password) {
		StringBuilder sb = new StringBuilder(url);
		sb.append(" ");
		if (username != null)
			sb.append(username);
		sb.append(" ");
		if (password != null)
			sb.append(password);
		return url + " " + username + " " + password;
	}

}
